#include "StdAfx.h"
#include "netmgr.h"

INT32 CSvrPacketParser::ParsePacket( const char* pData, const INT32 iLen )
{
    if (iLen < sizeof(INT32))
    {
        return 0;
    }

    INT32 iPkglen = *(INT32*)pData;

    if (iPkglen > iLen)
    {
        return 0;
    }

    return iPkglen;
}

INSTANCE_SINGLETON(CNetMgr)

CNetMgr::CNetMgr(void)
{
}

CNetMgr::~CNetMgr(void)
{
}

bool CNetMgr::Init( void )
{
    m_net_mgr = CreateNetManager(NET_IO_COMPLETEPORT, this);
    if (!m_net_mgr)
    {
        return false;
    }

    m_listen_client = m_net_mgr->Listen("0", 42158, 1024, 1024, &m_pkg_parser);
    if (!m_listen_client)
    {
        return false;
    }

    m_listen_nat_test = m_net_mgr->Listen("0", 42159, 1024, 1024, &m_pkg_parser);
    if (!m_listen_nat_test)
    {
        return false;
    }

    return true;
}

void CNetMgr::UnInit( void )
{
    if (m_listen_client)
    {
        m_net_mgr->CloseNetHandle(m_listen_client);
    }

    if (m_listen_nat_test)
    {
        m_net_mgr->CloseNetHandle(m_listen_nat_test);
    }

    if (m_net_mgr)
    {
        m_net_mgr->Release();
        m_net_mgr = NULL;
    }
}

void CNetMgr::OnEstablish( HNETHANDLE hHandle, HSESSION hSession )
{
    if (hHandle == m_listen_client)
    {
        CClient* client = m_pool_client.AllocObj();
        if (!client)
        {
            m_net_mgr->DisConnect(hSession);
            return;
        }

        client->Reset();

        m_net_mgr->SetSessionUserData(hSession, client);
        client->OnEstablish(hHandle, hSession);
    }
    else if (hHandle == m_listen_nat_test)
    {
        CNATTestSession* nat_test_session = m_pool_nat_test_session.AllocObj();
        if (!nat_test_session)
        {
            m_net_mgr->DisConnect(hSession);
            return;
        }

        nat_test_session->Reset();

        m_net_mgr->SetSessionUserData(hSession, nat_test_session);
        nat_test_session->OnEstablish(hHandle, hSession);
    }
    else
    {
        ISession* session = (ISession*)m_net_mgr->GetSessionUserData(hSession);

        if (!session)
            return;

        session->OnEstablish(hHandle, hSession);
    }
}

void CNetMgr::OnTerminate( HSESSION hSession )
{
    ISession* session = (ISession*)m_net_mgr->GetSessionUserData(hSession);

    if (!session)
        return;

    HNETHANDLE net_handle = session->net_handle();

    session->OnTerminate(hSession);

    if (net_handle == m_listen_client)
    {
        m_pool_client.FreeObj((CClient*)session);
    }
    else if (net_handle == m_listen_nat_test)
    {
        m_pool_nat_test_session.FreeObj((CNATTestSession*)session);
    }
}

void CNetMgr::OnError( HNETHANDLE hHandle, HSESSION hSession, INT32 iModuleError, INT32 iSystemError )
{
    ISession* session = (ISession*)m_net_mgr->GetSessionUserData(hSession);

    if (!session)
        return;

    session->OnError(hHandle, hSession, iModuleError, iSystemError);
}

void CNetMgr::OnRecv( HSESSION hSession, const char* pData, const INT32 iLen )
{
    ISession* session = (ISession*)m_net_mgr->GetSessionUserData(hSession);

    if (!session)
        return;

    session->OnRecv(hSession, pData, iLen);
}

bool CNetMgr::Run( void )
{
    return m_net_mgr->Run(10);
}

